From 78d264da22bbe96f63193b029071668fdf048446 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 4 Aug 2004 14:36:41 +0000 Subject: [PATCH] bitkeeper revision 1.1145 (4110f479PxkIKUvFbncA2zFohr9-Gg) Allow guests to register for synchronous callback (exception 15) when a 4GB segment access is emulated by Xen. This will be used by Linux to dynamically rewrite common instructions. --- .rootkeys | 1 + .../arch/xen/i386/kernel/entry.S | 5 ++- .../arch/xen/i386/kernel/setup.c | 2 ++ .../arch/xen/i386/kernel/traps.c | 13 ++----- .../arch/xen/kernel/Makefile | 2 +- .../arch/xen/kernel/fixup.c | 31 ++++++++++++++++ xen/arch/x86/traps.c | 35 +++++++++---------- xen/arch/x86/x86_32/emulate.c | 14 ++++++++ xen/include/hypervisor-ifs/hypervisor-if.h | 3 +- 9 files changed, 71 insertions(+), 35 deletions(-) create mode 100644 linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c diff --git a/.rootkeys b/.rootkeys index 26c3572bfe..eb5a018d7d 100644 --- a/.rootkeys +++ b/.rootkeys @@ -165,6 +165,7 @@ 40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c 40f56239pYRq5yshPTkv3ujXKc8K6g linux-2.6.7-xen-sparse/arch/xen/kernel/empty.c 40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.7-xen-sparse/arch/xen/kernel/evtchn.c +4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c 40f56239sFcjHiIRmnObRIDF-zaeKQ linux-2.6.7-xen-sparse/arch/xen/kernel/process.c 40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c 3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.7-xen-sparse/arch/xen/kernel/xen_proc.c diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/entry.S b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/entry.S index d4fd8e138d..4f137e8cea 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/entry.S +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/entry.S @@ -735,9 +735,8 @@ ENTRY(machine_check) jmp error_code #endif -ENTRY(spurious_interrupt_bug) - pushl $0 - pushl $do_spurious_interrupt_bug +ENTRY(fixup_4gb_segment) + pushl $do_fixup_4gb_segment jmp error_code .data diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c index e2fea04403..5845544046 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c @@ -1098,6 +1098,8 @@ void __init setup_arch(char **cmdline_p) HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); + HYPERVISOR_vm_assist(VMASST_CMD_enable, + VMASST_TYPE_4gb_segments_notify); #if 0 HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writeable_pagetables); diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c index 4f0811576a..b60b3abfc4 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c @@ -89,7 +89,7 @@ asmlinkage void page_fault(void); asmlinkage void coprocessor_error(void); asmlinkage void simd_coprocessor_error(void); asmlinkage void alignment_check(void); -asmlinkage void spurious_interrupt_bug(void); +asmlinkage void fixup_4gb_segment(void); asmlinkage void machine_check(void); static int kstack_depth_to_print = 24; @@ -822,15 +822,6 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs, } } -asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs, - long error_code) -{ -#if 0 - /* No need to warn about this any longer. */ - printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); -#endif -} - /* * 'math_state_restore()' saves the current math information in the * old math state array, and gets the new ones from the current task @@ -953,7 +944,7 @@ static trap_info_t trap_table[] = { { 12, 0, __KERNEL_CS, (unsigned long)stack_segment }, { 13, 0, __KERNEL_CS, (unsigned long)general_protection }, { 14, 0, __KERNEL_CS, (unsigned long)page_fault }, - { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug }, + { 15, 0, __KERNEL_CS, (unsigned long)fixup_4gb_segment }, { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error }, { 17, 0, __KERNEL_CS, (unsigned long)alignment_check }, #ifdef CONFIG_X86_MCE diff --git a/linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile b/linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile index eca4bdbab0..49714c6bfa 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile @@ -9,4 +9,4 @@ $(obj)/vmlinux.lds.s: arch/$(ARCH)/$(XENARCH)/kernel/vmlinux.lds.s extra-y += vmlinux.lds.s -obj-y := ctrl_if.o evtchn.o process.o reboot.o xen_proc.o empty.o +obj-y := ctrl_if.o evtchn.o fixup.o process.o reboot.o xen_proc.o empty.o diff --git a/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c b/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c new file mode 100644 index 0000000000..480483ef7b --- /dev/null +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c @@ -0,0 +1,31 @@ +/****************************************************************************** + * fixup.c + * + * Binary-rewriting of certain IA32 instructions, on notification by Xen. + * Used to avoid repeated slow emulation of common instructions used by the + * user-space TLS (Thread-Local Storage) libraries. + * + * Copyright (c) 2004, K A Fraser + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +asmlinkage void do_fixup_4gb_segment(struct pt_regs *regs, long error_code) +{ +} diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 7551d17260..5e5202c961 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1,7 +1,7 @@ /****************************************************************************** * arch/i386/traps.c * - * Modifications to Linux original are copyright (c) 2002-2003, K A Fraser + * Modifications to Linux original are copyright (c) 2002-2004, K A Fraser * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,6 @@ */ /* - * xen/arch/i386/traps.c - * * Copyright (C) 1991, 1992 Linus Torvalds * * Pentium III FXSR, SSE support @@ -220,30 +218,29 @@ static inline void do_trap(int trapnr, char *str, #define DO_ERROR_NOCODE(trapnr, str, name) \ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ { \ -do_trap(trapnr, str, regs, error_code, 0); \ + do_trap(trapnr, str, regs, error_code, 0); \ } #define DO_ERROR(trapnr, str, name) \ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ { \ -do_trap(trapnr, str, regs, error_code, 1); \ + do_trap(trapnr, str, regs, error_code, 1); \ } DO_ERROR_NOCODE( 0, "divide error", divide_error) - DO_ERROR_NOCODE( 4, "overflow", overflow) - DO_ERROR_NOCODE( 5, "bounds", bounds) - DO_ERROR_NOCODE( 6, "invalid operand", invalid_op) - DO_ERROR_NOCODE( 9, "coprocessor segment overrun", coprocessor_segment_overrun) - DO_ERROR(10, "invalid TSS", invalid_TSS) - DO_ERROR(11, "segment not present", segment_not_present) - DO_ERROR(12, "stack segment", stack_segment) -/* Vector 15 reserved by Intel */ - DO_ERROR_NOCODE(16, "fpu error", coprocessor_error) - DO_ERROR(17, "alignment check", alignment_check) - DO_ERROR_NOCODE(18, "machine check", machine_check) - DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error) - - asmlinkage void do_int3(struct pt_regs *regs, long error_code) +DO_ERROR_NOCODE( 4, "overflow", overflow) +DO_ERROR_NOCODE( 5, "bounds", bounds) +DO_ERROR_NOCODE( 6, "invalid operand", invalid_op) +DO_ERROR_NOCODE( 9, "coprocessor segment overrun", coprocessor_segment_overrun) +DO_ERROR(10, "invalid TSS", invalid_TSS) +DO_ERROR(11, "segment not present", segment_not_present) +DO_ERROR(12, "stack segment", stack_segment) +DO_ERROR_NOCODE(16, "fpu error", coprocessor_error) +DO_ERROR(17, "alignment check", alignment_check) +DO_ERROR_NOCODE(18, "machine check", machine_check) +DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error) + +asmlinkage void do_int3(struct pt_regs *regs, long error_code) { struct domain *p = current; struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id(); diff --git a/xen/arch/x86/x86_32/emulate.c b/xen/arch/x86/x86_32/emulate.c index aac7aa071d..b2acb6783a 100644 --- a/xen/arch/x86/x86_32/emulate.c +++ b/xen/arch/x86/x86_32/emulate.c @@ -502,6 +502,20 @@ int gpf_emulate_4gb(struct pt_regs *regs) /* Success! */ perfc_incrc(emulations); regs->eip += pb - eip; + + /* If requested, give a callback on otherwise unused vector 15. */ + if ( VM_ASSIST(d, VMASST_TYPE_4gb_segments_notify) ) + { + ti = &d->thread.traps[15]; + gtb = &guest_trap_bounce[d->processor]; + gtb->flags = GTBF_TRAP; + gtb->error_code = pb - eip; + gtb->cs = ti->cs; + gtb->eip = ti->address; + if ( TI_GET_IF(ti) ) + d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1; + } + return 1; undecodeable: diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h index 1c9aef8f53..bc8515425a 100644 --- a/xen/include/hypervisor-ifs/hypervisor-if.h +++ b/xen/include/hypervisor-ifs/hypervisor-if.h @@ -188,7 +188,8 @@ #define VMASST_CMD_enable 0 #define VMASST_CMD_disable 1 #define VMASST_TYPE_4gb_segments 0 -#define VMASST_TYPE_writeable_pagetables 1 +#define VMASST_TYPE_4gb_segments_notify 1 +#define VMASST_TYPE_writeable_pagetables 2 #ifndef __ASSEMBLY__ -- 2.30.2